/*
 * Copyright (C) 2010 TopCoder Inc., All Rights Reserved.
 */
package com.hercules.xre.protocol.testing.netty;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.ChannelGroupFuture;
import org.jboss.netty.channel.group.ChannelGroupFutureListener;

import com.hercules.xre.protocol.testing.Helper;
import com.topcoder.util.log.Log;
import com.topcoder.util.log.LogManager;
/**
 * <p>
 * Channel Group Future Listener that is responsible for logging errors that might occur
 * when performing I/O operations on group of channels.
 * </p>
 * <p>
 * <strong>Thread-safety:</strong> This class is immutable and thus it is thread safe.
 * </p>
 * @author TCSDESIGNER, TCSDEVELOPER
 * @version 1.0
*/
public class ExceptionHandlingChannelGroupFutureListener implements ChannelGroupFutureListener {
    /**
     * <p>
     * Logger that is used to log activities and errors.
     * </p>
     * <p>
     * It is initialized to LogManager.getLog(ExceptionHandlingChannelGroupFutureListener.class.getName()).
     * Can not be null, never changes after initialization.
     * </p>
    */
    private static final Log LOGGER = LogManager.getLog(ExceptionHandlingChannelGroupFutureListener.class.getName());
    /**
     * Empty default constructor.
    */
    public ExceptionHandlingChannelGroupFutureListener() {
    }
    /**
     * <p>
     * Method called by Netty framework when channel group operation has been completed.
     * If an exception was thrown during operation it should be caught and logged.
     * </p>
     * @param future channel group future representing message delivery event, can't be null
     * @throws IllegalArgumentException when passed future is null
    */
    public void operationComplete(ChannelGroupFuture future) {
        final String signature = "ExceptionHandlingChannelGroupFutureListener#operationComplete";
        Helper.logEnter(signature, new String[] {"future"}, new Object[] {future}, LOGGER);
        try {
            Helper.checkNull(future, "future", signature, LOGGER);
            if (future.isPartialFailure() || future.isCompleteFailure()) {
                ChannelGroup group = future.getGroup();
                for (Channel channel : group) {
                    if (channel != null) {
                        ChannelFuture channelFuture = future.find(channel);
                        if (channelFuture != null) {
                            Throwable cause = channelFuture.getCause();
                            if (cause != null) {
                                // log exception
                                Helper.logError(cause, signature, LOGGER);
                            }
                        }
                    }
                }
            }
        } finally {
            Helper.logExit(signature, null, LOGGER);
        }
    }
}

